package com.behome.netty.netty_A.server;

import com.behome.common.constant.SystemSetConstants;
import com.behome.netty.netty_B.server.StandardBNettyServer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;


/**
 * 国标附录A 协议服务端 内网
 */
@Slf4j
public class StandardAPrivateNettyServer {

    private static EventLoopGroup bossGroup;
    private static EventLoopGroup workerGroup;
    private static StandardAPrivateNettyServer instance;
     public static StandardAPrivateNettyServer getMe(){
        if(instance == null){
            instance = new StandardAPrivateNettyServer();
            bossGroup = new NioEventLoopGroup(1);
            workerGroup = new NioEventLoopGroup();
        }
        return instance;
    }

    public void start() {
        //配置服务端的NIO线程组
        try {
            ServerBootstrap bootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)  // 绑定线程池
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        public void initChannel(SocketChannel channel) {
                            channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024, 5, 4, 80, 0));
                            channel.pipeline().addLast(new StandardADecoder());
                            channel.pipeline().addLast(new ByteArrayEncoder());
                            channel.config().setWriteBufferHighWaterMark(1024 * 1024 * 8);
                            channel.pipeline().addLast(new IdleStateHandler(60, 0, 0), new StandardAPrivateServerHandler());
                        }
                    })
//                    .childHandler(new StandardANettyServerChannelInitializer())//编码解码
                    .option(ChannelOption.SO_BACKLOG, 128)  //服务端接受连接的队列长度，如果队列已满，客户端连接将被拒绝
//                    .childOption(ChannelOption.SO_SNDBUF, 32 * 1024) // 设置发送缓冲大小
//                    .childOption(ChannelOption.SO_RCVBUF, 32 * 1024) // 这是接收缓冲大小
//                    .option(ChannelOption.SO_KEEPALIVE, true) // 保持连接
                    //.childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                    .childOption(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator(64, 2048, 65536))
                    .childOption(ChannelOption.SO_KEEPALIVE, true);  //保持长连接，2小时无数据激活心跳机制
            // 绑定端口，开始接收进来的连接
            ChannelFuture future = bootstrap.bind(SystemSetConstants.GB089_A_PRIVATE_PORT).sync();
            log.info("监听附录A接收端口[内网]：" + SystemSetConstants.GB089_A_PRIVATE_PORT);
            //关闭channel和块，直到它被关闭
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public void stop() {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }

}
